/******************************************************************************
*
* MODULE:    Alu.v
* DEVICE:     Alu
* PROJECT:   Tarea 3 Diseño Electronico Digital
* AUTHOR:    Ricardo Dávila Castro   
* DATE:      2010 21:15:58
*
* ABSTRACT:   UNIDAD ARITMETICO LOGICAEjercicio 1
*            
******************************************************************************/

`ifndef 	ALU
`define    ALU

module Alu(DatoInA, DatoInB,Shampt, Operacion, AluResult, Zero);
input [4:0] Shampt;
input [31:0] DatoInA, DatoInB;
input [4:0] Operacion;
output reg  [31:0] AluResult;
output Zero;

always @ (*) 
   begin
    case (Operacion)
      'h00:  AluResult = DatoInA&DatoInB; //and
      'h01:  AluResult = DatoInA|DatoInB; //or
      'h02:  AluResult = DatoInA+DatoInB; //add suma
      'h03:  AluResult = DatoInA^DatoInB; //xor
      'h04:  AluResult = DatoInA~^DatoInB; //xnor
      'h05:  AluResult = DatoInA; // transfer
      'h06:  AluResult = DatoInA-DatoInB; //Zero= (!AluResult)? 1:0 ; end//subtract resta 
      'h07:  begin 
                /*if(DatoInB<DatoInA) */ AluResult = 32'h ff_ff_ff_ff;
                //if(DatoInB>=DatoInA) AluResult = 32'h 00_00_00_00;
             end  
      'h08:  AluResult= DatoInA+DatoInB+1; //add with Carry
      'h09:  AluResult = DatoInA+~(DatoInB); //subs with borrow
      'h0A:  AluResult = DatoInA+1; //increment
      'h0B:  AluResult = DatoInA-1; //decrement
      'h0C:  AluResult = ~(DatoInA|DatoInB); //NOR
      'h0D:  AluResult = ~(DatoInA&DatoInB); //NAND  
      'h0E:  AluResult = DatoInA  >> DatoInB[4:0];//Shampt[4:0]; //shift right
      'h0F:  AluResult = DatoInA  << DatoInB[4:0];//Shampt[4:0]; //shift left 
      'h10:  AluResult = 0; //clear
      'h11:  begin 
      			case (DatoInB[4:0]) //Rotate shift Right
      				'h00: AluResult = DatoInA;
      				'h01: AluResult = {DatoInA[0],DatoInA[31:1]};
      				'h02: AluResult = {DatoInA[1:0],DatoInA[31:2]};
      				'h03: AluResult = {DatoInA[2:0],DatoInA[31:3]};
      				'h04: AluResult = {DatoInA[3:0],DatoInA[31:4]};
      				'h05: AluResult = {DatoInA[4:0],DatoInA[31:5]};
      				'h06: AluResult = {DatoInA[5:0],DatoInA[31:6]};
      				'h07: AluResult = {DatoInA[6:0],DatoInA[31:7]};
      				'h08: AluResult = {DatoInA[7:0],DatoInA[31:8]};
      				'h09: AluResult = {DatoInA[8:0],DatoInA[31:9]};
      				'h0A: AluResult = {DatoInA[9:0],DatoInA[31:10]};
      				'h0B: AluResult = {DatoInA[10:0],DatoInA[31:11]};
      				'h0C: AluResult = {DatoInA[11:0],DatoInA[31:12]};
      				'h0D: AluResult = {DatoInA[12:0],DatoInA[31:13]};
      				'h0E: AluResult = {DatoInA[13:0],DatoInA[31:14]};
      				'h0F: AluResult = {DatoInA[14:0],DatoInA[31:15]};
      				'h10: AluResult = {DatoInA[15:0],DatoInA[31:16]};
      				'h11: AluResult = {DatoInA[16:0],DatoInA[31:17]};
      				'h12: AluResult = {DatoInA[17:0],DatoInA[31:18]};
      				'h13: AluResult = {DatoInA[18:0],DatoInA[31:19]};
      				'h14: AluResult = {DatoInA[19:0],DatoInA[31:20]};
      				'h15: AluResult = {DatoInA[20:0],DatoInA[31:21]};
      				'h16: AluResult = {DatoInA[21:0],DatoInA[31:22]};
      				'h17: AluResult = {DatoInA[22:0],DatoInA[31:23]};
      				'h18: AluResult = {DatoInA[23:0],DatoInA[31:24]};
      				'h19: AluResult = {DatoInA[24:0],DatoInA[31:25]};
      				'h1A: AluResult = {DatoInA[25:0],DatoInA[31:26]};
      				'h1B: AluResult = {DatoInA[26:0],DatoInA[31:27]};
      				'h1C: AluResult = {DatoInA[27:0],DatoInA[31:28]};
      				'h1D: AluResult = {DatoInA[28:0],DatoInA[31:29]};
      				'h1E: AluResult = {DatoInA[29:0],DatoInA[31:30]};
      				'h1F: AluResult = {DatoInA[30:0],DatoInA[31]};
      				//'h20: AluResutl = {DatoInA[31:0],DatoInA[31:1]}
      				
      			endcase
      		 end
      'h12: begin 
      			case (DatoInB[4:0]) //Rotate Shift Left
      				'h0: AluResult = DatoInA;
      				'h01: AluResult = {DatoInA[30:0],DatoInA[31]};
      				'h02: AluResult = {DatoInA[29:0],DatoInA[31:30]};
      				'h03: AluResult = {DatoInA[28:0],DatoInA[31:29]};
      				'h04: AluResult = {DatoInA[27:0],DatoInA[31:28]};
      				'h05: AluResult = {DatoInA[26:0],DatoInA[31:27]};
      				'h06: AluResult = {DatoInA[25:0],DatoInA[31:26]};
      				'h07: AluResult = {DatoInA[24:0],DatoInA[31:25]};
      				'h08: AluResult = {DatoInA[23:0],DatoInA[31:24]};
      				'h09: AluResult = {DatoInA[22:0],DatoInA[31:23]};
      				'h0A: AluResult = {DatoInA[21:0],DatoInA[31:22]};
      				'h0B: AluResult = {DatoInA[20:0],DatoInA[31:21]};
      				'h0C: AluResult = {DatoInA[19:0],DatoInA[31:20]};
      				'h0D: AluResult = {DatoInA[18:0],DatoInA[31:19]};
      				'h0E: AluResult = {DatoInA[17:0],DatoInA[31:18]};
      				'h0F: AluResult = {DatoInA[16:0],DatoInA[31:17]};
      				'h10: AluResult = {DatoInA[15:0],DatoInA[31:16]};
      				'h11: AluResult = {DatoInA[14:0],DatoInA[31:15]};
      				'h12: AluResult = {DatoInA[13:0],DatoInA[31:14]};
      				'h13: AluResult = {DatoInA[12:0],DatoInA[31:13]};
      				'h14: AluResult = {DatoInA[11:0],DatoInA[31:12]};
      				'h15: AluResult = {DatoInA[10:0],DatoInA[31:11]};
      				'h16: AluResult = {DatoInA[9:0],DatoInA[31:10]};
      				'h17: AluResult = {DatoInA[8:0],DatoInA[31:9]};
      				'h18: AluResult = {DatoInA[7:0],DatoInA[31:8]};
      				'h19: AluResult = {DatoInA[6:0],DatoInA[31:7]};
      				'h1A: AluResult = {DatoInA[4:0],DatoInA[31:6]};
      				'h1B: AluResult = {DatoInA[4:0],DatoInA[31:5]};
      				'h1C: AluResult = {DatoInA[3:0],DatoInA[31:4]};
      				'h1D: AluResult = {DatoInA[2:0],DatoInA[31:3]};
      				'h1E: AluResult = {DatoInA[1:0],DatoInA[31:2]};
      				'h1F: AluResult = {DatoInA[0],DatoInA[31:1]};
      			endcase
      		 end  
      'h13:  begin 
      			case (DatoInB[4:0]) // Arithmetic Shift Right
      				'h0: AluResult = DatoInA;
      				'h01: AluResult = {DatoInA[31],DatoInA[31:1]};
      				'h02: AluResult = {{2{DatoInA[31]}},DatoInA[31:2]};
      				'h03: AluResult = {{3{DatoInA[31]}},DatoInA[31:3]};
      				'h04: AluResult = {{4{DatoInA[31]}},DatoInA[31:4]};
      				'h05: AluResult = {{5{DatoInA[31]}},DatoInA[31:5]};
      				'h06: AluResult = {{6{DatoInA[31]}},DatoInA[31:6]};
      				'h07: AluResult = {{7{DatoInA[31]}},DatoInA[31:7]};
      				'h08: AluResult = {{8{DatoInA[31]}},DatoInA[31:8]};
      				'h09: AluResult = {{9{DatoInA[31]}},DatoInA[31:9]};
      				'h0A: AluResult = {{10{DatoInA[31]}},DatoInA[31:10]};
      				'h0B: AluResult = {{11{DatoInA[31]}},DatoInA[31:11]};
      				'h0C: AluResult = {{12{DatoInA[31]}},DatoInA[31:12]};
      				'h0D: AluResult = {{13{DatoInA[31]}},DatoInA[31:13]};
      				'h0E: AluResult = {{14{DatoInA[31]}},DatoInA[31:14]};
      				'h0F: AluResult = {{15{DatoInA[31]}},DatoInA[31:15]};
      				'h10: AluResult = {{16{DatoInA[31]}},DatoInA[31:16]};
      				'h11: AluResult = {{17{DatoInA[31]}},DatoInA[31:17]};
      				'h12: AluResult = {{18{DatoInA[31]}},DatoInA[31:18]};
      				'h13: AluResult = {{19{DatoInA[31]}},DatoInA[31:19]};
      				'h14: AluResult = {{20{DatoInA[31]}},DatoInA[31:20]};
      				'h15: AluResult = {{21{DatoInA[31]}},DatoInA[31:21]};
      				'h16: AluResult = {{22{DatoInA[31]}},DatoInA[31:22]};
      				'h17: AluResult = {{23{DatoInA[31]}},DatoInA[31:23]};
      				'h18: AluResult = {{24{DatoInA[31]}},DatoInA[31:24]};
      				'h19: AluResult = {{25{DatoInA[31]}},DatoInA[31:25]};
      				'h1A: AluResult = {{26{DatoInA[31]}},DatoInA[31:26]};
      				'h1B: AluResult = {{27{DatoInA[31]}},DatoInA[31:27]};
      				'h1C: AluResult = {{28{DatoInA[31]}},DatoInA[31:28]};
      				'h1D: AluResult = {{29{DatoInA[31]}},DatoInA[31:29]};
      				'h1E: AluResult = {{30{DatoInA[31]}},DatoInA[31:30]};
      				'h1F: AluResult = {{31{DatoInA[31]}},DatoInA[31]};
      			endcase
      		 end
      
      'h14:  AluResult = DatoInA  << DatoInB[4:0]; //clear
      default :
         AluResult=0;
    endcase
  end
  assign Zero = (AluResult==0)? 1 : 0;
endmodule
`endif